{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": null,
        "height": 2,
        "hidden": true,
        "row": null,
        "width": 2
       }
      }
     }
    }
   },
   "source": [
    "<img src=\"../common/rfsoc_book_banner.jpg\" alt=\"University of Strathclyde\" align=\"left\">"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": null,
        "height": 2,
        "hidden": true,
        "row": null,
        "width": 2
       }
      }
     }
    },
    "tags": []
   },
   "source": [
    "<div class=\"alert alert-block\" style=\"background-color: #c7b8d6; padding: 10px\">\n",
    "    <p style=\"color: #222222\">\n",
    "        <b>Note:</b>\n",
    "        <br>\n",
    "        This Jupyter notebook uses hardware features of the Zynq UltraScale+ RFSoC device. Therefore, the notebook cells will only execute successfully on an RFSoC platform.\n",
    "        <br>\n",
    "        <b>This Jupyter notebook is not compatible with the ZCU216 development board as the RFSoC-SAM module does not support this platform.</b>\n",
    "    </p>\n",
    "</div>\n",
    "\n",
    "# Notebook Set C\n",
    "\n",
    "---\n",
    "\n",
    "## 02 - RFSoC Spectrum Analyser\n",
    "In the previous notebook, we used a subset of the functionality offered by the open-source RFSoC spectrum analyser module (RFSoC-SAM) [1]. We will now explore the full capabilities of the flexible hardware accelerated spectrum analyser. This investigation will involve the use of Voila [2], which is a software library for converting a Jupyter notebook into an interactive dashboard.\n",
    "\n",
    "## Table of Contents\n",
    "* [1. Introduction](#introduction)\n",
    "* [2. Launching the Spectrum Analyser](#launch-spectrum)\n",
    "* [3. Using the Spectrum Analyser](#using-spectrum)\n",
    "* [4. Conclusion](#conclusion)\n",
    "\n",
    "## References\n",
    "* [1] - [StrathSDR, \"RFSoC Spectrum Analyser Module (RFSoC-SAM)\", GitHub Repository.](https://github.com/strath-sdr/rfsoc_sam)\n",
    "* [2] - [Voila, \"voila, Rendering of live Jupyter notebooks with interactive widgets\", GitHub Repository.](https://github.com/voila-dashboards/voila)\n",
    "\n",
    "## Revision\n",
    "* **v1.0** | 17/01/23 | *First Revision*\n",
    "* **v1.1** | 19/05/23 | *Minor changes for new development boards (ZCU208 & ZCU216)*\n",
    "\n",
    "---\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": null,
        "height": 2,
        "hidden": true,
        "row": null,
        "width": 2
       }
      }
     }
    }
   },
   "source": [
    "## 1. Introduction <a class=\"anchor\" id=\"introduction\"></a>\n",
    "The Zynq UltraScale+ RFSoC contains high frequency samplers known as RF Data Converters (RF DCs). The RF DCs are tightly coupled with the Programmable Logic (PL), creating a high-throughput, low-latency path between the FPGA and analogue world. The RFSoC Spectrum Analyser Module (RFSoC-SAM) [1] employs the RF Analogue-to-Digital Converters (RF ADCs) to receive RF time domain signals. The received data is manipulated using spectral pre-processing techniques in the PL, to prepare it for frequency domain analysis and visualisation in the Processing System (PS).\n",
    "\n",
    "A significant portion of the design has been implemented in the RFSoC's PL to prevent the PS from applying highly computational arithmetic. There is a spectrum analyser for each available RF ADC channel in the design. The spectrum Analysers are also interfaced to their very own flexible decimator, allowing different sample rates to be configured for each channel.\n",
    "\n",
    "To setup the RFSoC platform for this demonstration, please follow the hardware setup instructions outlined in the [previous notebook](01_exploring_the_spectrum.ipynb)."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": null,
        "height": 2,
        "hidden": true,
        "row": null,
        "width": 2
       }
      }
     }
    }
   },
   "source": [
    "## 2. Launching the Spectrum Analyser <a class=\"anchor\" id=\"launch-spectrum\"></a>\n",
    "Voila can be used to launch the spectrum analyser, while ignoring all of the markdown and code cells typically found in a normal Jupyter notebook. The Voila dashboard can be launched following the instructions below:\n",
    "\n",
    "* Click on the \"Open with Voila Gridstack in a new browser tab\" button at the top of the screen:\n",
    "\n",
    "<figure>\n",
    "<img src='images/open_voila.png' height='50%' width='50%'/>\n",
    "</figure>\n",
    "\n",
    "After the new tab opens the kernel will start and the notebook will run. Only the Spectrum Analyzer will be displayed. The initialisation process takes around 1 minute.\n",
    "\n",
    "Below are the code cells that will be ran when Voila is called. The procedure is fairly simple. Load the RFSoC-SAM library, initialise the overlay, and display the spectrum analyser. You do not need to run these code cells individually to create the Voila dashboard. Follow the Voila instructions above instead."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": null,
        "height": 2,
        "hidden": true,
        "row": null,
        "width": 2
       }
      }
     }
    }
   },
   "outputs": [],
   "source": [
    "from rfsoc_sam.overlay import Overlay\n",
    "\n",
    "sam = Overlay(init_rf_clks=True)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": null,
        "height": 2,
        "hidden": true,
        "row": null,
        "width": 2
       }
      }
     }
    }
   },
   "source": [
    "Now, launch the spectrum analyser."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": 0,
        "height": 16,
        "hidden": false,
        "row": 0,
        "width": 12
       }
      }
     }
    }
   },
   "outputs": [],
   "source": [
    "sam.spectrum_analyzer_application()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": null,
        "height": 2,
        "hidden": true,
        "row": null,
        "width": 2
       }
      }
     }
    }
   },
   "source": [
    "## 3. Using the Spectrum Analyser <a class=\"anchor\" id=\"using-spectrum\"></a>\n",
    "After the spectrum analyser has launched in the new tab, you will be able to interact with its configuration and controls. The spectrum analyser user interface is displayed below. Various parts of the interface have been highlighted.\n",
    "\n",
    "<figure>\n",
    "<img src='images/spectrum_analyser.png' height='80%' width='80%'/>\n",
    "</figure>\n",
    "\n",
    "* 1. The user can swap between ADC channels using this control panel.\n",
    "* 2. The frequency spectrum is displayed here.\n",
    "* 3. This control panel can be used to switch on the spectrum analyser and spectrogram. Centre frequency selection and bandwidth control can also be configured using the control panel's drop down widgets.\n",
    "* 4. The spectrogram is displayed here.\n",
    "* 5. This text box displays the current sample frequency and FFT resolution.\n",
    "\n",
    "As an exercise on using the spectrum analyser, try to configure it to inspect frequency bands from the [previous notebook](01_exploring_the_spectrum.ipynb). You can also explore your ambient radio environment at your own leisure."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": null,
        "height": 2,
        "hidden": true,
        "row": null,
        "width": 2
       }
      }
     }
    }
   },
   "source": [
    "## 4. Conclusion <a class=\"anchor\" id=\"conclusion\"></a>\n",
    "This notebook has presented the RFSoC Spectrum Analyser. We used Voila to launch the spectrum analyser into an interactive dashboard. We investigated several controls of the spectrum analyser and explore the ambient radio environment.\n",
    "\n",
    "In the following notebook, we will investigate Fourier's Theorem."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "extensions": {
     "jupyter_dashboards": {
      "activeView": "grid_default",
      "views": {
       "grid_default": {
        "col": null,
        "height": 2,
        "hidden": true,
        "row": null,
        "width": 2
       }
      }
     }
    }
   },
   "source": [
    "---\n",
    "\n",
    "[⬅️ Previous Notebook](01_exploring_the_spectrum.ipynb) || [Next Notebook 🚀](03_fouriers_theorem.ipynb)\n",
    "\n",
    "Copyright © 2023 Strathclyde Academic Media\n",
    "\n",
    "---\n",
    "---"
   ]
  }
 ],
 "metadata": {
  "extensions": {
   "jupyter_dashboards": {
    "activeView": "grid_default",
    "version": 1,
    "views": {
     "grid_default": {
      "cellMargin": 2,
      "defaultCellHeight": 60,
      "maxColumns": 12,
      "name": "grid",
      "type": "grid"
     }
    }
   }
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
